﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;

namespace KoSoft
{
	public class UtilXml
	{
		//定义XML文件的路径
		protected string strXmlFile;

		//定义xml文档；
		protected XmlDocument xmlDoc = new XmlDocument();

		//xmlHelper的构造函数
		//参数xmlFile为xml文件的存储路径
		//参数 bOverWrite只是是否复写（重新创建xml文档）
		//sroot为创建的根元素
		public UtilXml(string xmlUrl, string rootName, Boolean isOverWrite = false)
		{
			try
			{
				//如果覆盖模式，则强行创建一个xml文档
				if (isOverWrite)
				{
					xmlDoc.AppendChild(xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null));//设置xml的版本，格式信息
					xmlDoc.AppendChild(xmlDoc.CreateElement("", rootName, ""));//创建根元素
					xmlDoc.Save(xmlUrl);//保存
				}
				else //否则，检查文件是否存在，不存在则创建
				{
					if (!File.Exists(xmlUrl))
					{
						xmlDoc.AppendChild(xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null));
						xmlDoc.AppendChild(xmlDoc.CreateElement("", rootName, ""));
						xmlDoc.Save(xmlUrl);
					}
				}
				xmlDoc.Load(xmlUrl);
			}
			catch (System.Exception ex)
			{
				throw ex;
			}
			strXmlFile = xmlUrl;
		}

		public string GetAttrValue(string xPath, string attrKey)
		{
			string result = "";
			try
			{
				XmlNode rootNode = xmlDoc.SelectSingleNode(xPath);
				result = rootNode.Attributes[attrKey].Value;
				return result;
			}
			catch (Exception e)
			{
				throw e;
			}
		}

		public string GetElementValue(string xPath)
		{
			string result = "";
			try
			{
				XmlNode rootNode = xmlDoc.SelectSingleNode(xPath);
				result = rootNode.InnerText;
				return result;
			}
			catch (Exception e)
			{
				throw e;
			}
		}

		public void InsertCData(string xPath, string elementKey, string cdata)
		{
			try
			{
				XmlNode rootNode = xmlDoc.SelectSingleNode(xPath);
				XmlElement newElement = xmlDoc.CreateElement(elementKey);
				XmlCDataSection cdataSec = xmlDoc.CreateCDataSection(cdata);
				newElement.AppendChild(cdataSec);
				rootNode.AppendChild(newElement);
			}
			catch (Exception e)
			{
				throw e;
			}
		}

		public void Insert(string xPath, string elementKey, string content)
		{
			Insert(xPath, elementKey, string.Empty, string.Empty, content);
		}

		public void Insert(string xPath, string elementKey, string attrKey, string attrValue)
		{
			Insert(xPath, elementKey, attrKey, attrValue, string.Empty);
		}

		public void Insert(string xPath, string elementKey, string attrKey, string attrValue, string content)
		{
			try
			{
				XmlNode rootNode = xmlDoc.SelectSingleNode(xPath);
				XmlElement newElement = xmlDoc.CreateElement(elementKey);
				newElement.SetAttribute(attrKey, attrValue);
				newElement.InnerText = content;
				rootNode.AppendChild(newElement);
			}
			catch (Exception e)
			{
				throw e;
			}
		}

		public void Insert(string xPath, string elementKey, string[] attrKeys, string[] attrValues, string content)
		{
			try
			{
				XmlNode rootNode = xmlDoc.SelectSingleNode(xPath);
				XmlElement newElement = xmlDoc.CreateElement(elementKey);
				for (int i = 0; i <= attrKeys.GetUpperBound(0); i++)
					newElement.SetAttribute(attrKeys[i], attrValues[i]);
				newElement.InnerText = content;
				rootNode.AppendChild(newElement);
			}
			catch (Exception e)
			{
				throw e;
			}
		}

		/// <summary>
		/// 更新节点内容
		/// </summary>
		/// <param name="xPathNode"></param>
		/// <param name="content"></param>
		public void Update(string xPathNode, string content)
		{
			try
			{
				xmlDoc.SelectSingleNode(xPathNode).InnerText = content;
			}
			catch (Exception e)
			{
				throw e;
			}
		}
		/// <summary>
		/// 更新节点的某个属性
		/// </summary>
		/// <param name="xPathNode">要操作的节点</param>
		/// <param name="attrName">属性名</param>
		/// <param name="attrValue">属性值</param>
		public void Update(string xPathNode, string attrName, string attrValue)
		{
			try
			{
				((XmlElement)(xmlDoc.SelectSingleNode(xPathNode))).SetAttribute(attrName, attrValue);
			}
			catch (Exception e)
			{
				throw e;
			}
		}
		/// <summary>
		/// 更新节点的属性(同步更新内容和属性,删除全部属性再添加)
		/// </summary>
		/// <param name="xPathNode">要操作节点的xpath语句</param>
		/// <param name="attrNames">属性名称字符串数组</param>
		/// <param name="attrValues">属性内容字符串数组</param>
		/// <param name="content">节点内容</param>
		public void Update(string xPathNode, string[] attrNames, string[] attrValues)
		{
			try
			{
				XmlNode xn = xmlDoc.SelectSingleNode(xPathNode);
				if (xn != null)
				{
					xn.Attributes.RemoveAll();
					for (int i = 0; i <= attrNames.GetUpperBound(0); i++)
						((XmlElement)(xn)).SetAttribute(attrNames[i], attrValues[i]);
				}
			}
			catch (Exception e)
			{

				throw e;
			}

		}
		/// <summary>
		/// 移除选定节点集的所有属性
		/// </summary>
		/// <param name="xPathNode"></param>
		public void RemoveAllAttrs(string xPath)
		{
			XmlNodeList xnl = xmlDoc.SelectNodes(xPath);
			foreach (XmlNode xn in xnl)
				xn.Attributes.RemoveAll();
		}

		public void RemoveAttr(string xPath, string attrKey)
		{
			try
			{
				XmlNode xnl = xmlDoc.SelectSingleNode(xPath);
				xnl.Attributes.RemoveNamedItem(attrKey);
			}
			catch (Exception e)
			{
				throw e;
			}
		}
		public void RemoveNode(string xPathNode)
		{
			try
			{
				string mainNode = xPathNode.Substring(0, xPathNode.LastIndexOf("/"));
				xmlDoc.SelectSingleNode(mainNode).RemoveChild(xmlDoc.SelectSingleNode(xPathNode));
			}
			catch (Exception e)
			{
				throw e;
			}
		}

		/// <summary>
		/// 根据xpath值查找节点
		/// </summary>
		/// <param name="xPath">要查找节点的xpath值</param>
		/// <returns>找到返回true,否则返回true</returns>
		public bool HasNode(string xPath)
		{
			try
			{
				if (xmlDoc.SelectSingleNode(xPath) != null)
					return true;
				else
					return false;
			}
			catch
			{
				return false;
			}
		}

		/// <summary>
		///保存文档
		/// </summary>
		public void Save()
		{
			try
			{
				xmlDoc.Save(strXmlFile);
			}
			catch (System.Exception ex)
			{
				throw ex;
			}
			xmlDoc = null;
		}
	}
}